package com.ochnas.volunteersignup.service;

import static com.ochnas.volunteersignup.ui.SharedConstants.SIMPLE_DATE_FORMAT;

import java.util.Date;

import javax.jws.WebService;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentFactory;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;

import com.ochnas.volunteersignup.domain.Event;
import com.ochnas.volunteersignup.domain.Position;
import com.ochnas.volunteersignup.domain.Time;
import com.ochnas.volunteersignup.domain.User;
@WebService(endpointInterface = "com.ochnas.volunteersignup.service.EventWebService")
public class EventWebServiceImpl implements EventWebService {

	private EventService eventService;
	private VolunteerService volunteerService;
	private UserService userService;
	
	@Override
	public String createEventDocLiteral(String xml) {
		try {
			Document doc = DocumentHelper.parseText(xml);
			
			// Parse for coordinator
			Node cNode = doc.selectSingleNode("/event/user[@role='coordinator']");
			long cId = Long.parseLong(cNode.valueOf("@id"));
			
			User u = new User();
			u.setId(cId);
			
			// Parse for start time
			Node stNode = doc.selectSingleNode("/event/time[@name='startTime']");
			Node stHourOfDayNode = stNode.selectSingleNode("hourOfDay");
			int stHourOfDay = Integer.parseInt(stHourOfDayNode.getText());
			Node stMinutesNode = stNode.selectSingleNode("minutes");
			int stMinutes = Integer.parseInt(stMinutesNode.getText());
			Time startTime = new Time(stHourOfDay, stMinutes);
			
			// Parse for end time
			Node etNode = doc.selectSingleNode("/event/time[@name='endTime']");
			Node etHourOfDayNode = etNode.selectSingleNode("hourOfDay");
			int etHourOfDay = Integer.parseInt(etHourOfDayNode.getText());
			Node etMinutesNode = etNode.selectSingleNode("minutes");
			int etMinutes = Integer.parseInt(etMinutesNode.getText());
			Time endTime = new Time(etHourOfDay, etMinutes);
			
			// Parse for basic event information
			String eName = doc.selectSingleNode("/event/name").getText();
			String eDescription = doc.selectSingleNode("/event/description").getText();
			Date startDate = SIMPLE_DATE_FORMAT.parse(doc.selectSingleNode("/event/date[@name='startDate']").getText());
			Date endDate = SIMPLE_DATE_FORMAT.parse(doc.selectSingleNode("/event/date[@name='endDate']").getText());
		
			Event e = new Event(eName,eDescription, u, startDate, endDate, startTime, endTime);
			Event dbEvent = eventService.createEvent(e);
			
			Document response = DocumentFactory.getInstance().createDocument();
			Element eventElement = response.addElement("event");
	        eventElement.addAttribute("id", String.valueOf(dbEvent.getId()));
	        
	        return response.asXML();
			
		} catch (DocumentException e) {
			throw new RuntimeException("Error parsing input xml", e);
		} catch (Exception e) {
			throw new RuntimeException("Error parsing input xml", e);
		}
		
	}

	@Override
	public void createPositionForEventDocLiteral(String xml) {
		try {
			Document doc = DocumentHelper.parseText(xml);
			
			// parse for name 
			String name = doc.selectSingleNode("/position/name").getText();
			// parse for description
			String description = doc.selectSingleNode("/position/description").getText();
			// parse for number of volunteers
			String reqVolunteers = doc.selectSingleNode("/position/requiredNumberOfVolunteers").getText();
			int requiredNumberOfVolunteers = Integer.parseInt(
					reqVolunteers);
			// parse for event id
			Node eNode = doc.selectSingleNode("/position/event");
			long eId = Long.parseLong(eNode.valueOf("@id"));
			// find event in database using eventService
			Event dbEvent = eventService.findEvent(eId);
			// create position in database using eventService
			eventService.createPositionForEvent(dbEvent, name, description, requiredNumberOfVolunteers);

		} catch (DocumentException e) {
			throw new RuntimeException("Error parsing input xml", e);
		}

	}

	public EventService getEventService() {
		return eventService;
	}

	public void setEventService(EventService eventService) {
		this.eventService = eventService;
	}

	@Override
	public Long createEventRPC(Event e) {
		Event dbEvent = eventService.createEvent(e);
		return dbEvent.getId();
	}

	@Override
	public void createPositionForEventRPC(long eventId, String name,
			String description, int requiredNumberOfVolunteers) {
		Event e = eventService.findEvent(eventId);
		eventService.createPositionForEvent(e, name, description, requiredNumberOfVolunteers);
		
	}

	public VolunteerService getVolunteerService() {
		return volunteerService;
	}

	public void setVolunteerService(VolunteerService volunteerService) {
		this.volunteerService = volunteerService;
	}

	@Override
	public void registerForPositionRPC(long positionId, long userId) {
		volunteerService.registerForPosition(positionId, userId);
		
	}

	@Override
	public void registerForPositionAndNotifyRPC(Position p, User user) {
		volunteerService.registerForEventByPosition(p, user);
	}

	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}


}
